home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / ndrivers / vesadrv.c < prev    next >
Text File  |  1993-12-06  |  8KB  |  229 lines

  1. /**
  2.  ** VESADRV.C ---- EGA, VGA, VESA Super VGA driver for GRX 1.03
  3.  **
  4.  ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5.  ** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
  6.  ** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
  7.  **
  8.  ** This file is distributed under the terms listed in the document
  9.  ** "copying.dj", available from DJ Delorie at the address above.
  10.  ** A copy of "copying.dj" should accompany this file; if not, a copy
  11.  ** should be available from where this file was obtained.  This file
  12.  ** may not be distributed without a verbatim copy of "copying.dj".
  13.  **
  14.  ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  15.  ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16.  **/
  17. #pragma  inline
  18.  
  19. #include <dos.h>
  20. #include "vdr.h"
  21.  
  22. char driver_name[]  = { "GRX 1.03 VESA driver" };
  23.  
  24. #define MAX_TEXT_MODES        20            /* maximum text mode table size */
  25. #define EGA_TEXT_START        6            /* start of the EGA mode table */
  26. #define EGA_TEXT_MODES        5            /* number of EGA text modes (incl end marker) */
  27. GrModeEntry text_mode_table[MAX_TEXT_MODES] = {
  28.     { 80,   25,      2,    0x007, SETUP_STANDARD },
  29.     { 40,   25,      16,    0x001, SETUP_STANDARD },
  30.     { 80,   25,      16,    0x003, SETUP_STANDARD },
  31.     { 80,   28,      16,    0x003, SETUP_8X14_FNT },
  32.     { 80,   50,      16,    0x003, SETUP_8X8_FNT  },
  33.     { 0,    0,      0,    UNSUP, 0          },
  34.     { 80,   25,      2,    0x007, SETUP_STANDARD },    /* EGA table */
  35.     { 40,   25,      16,    0x001, SETUP_STANDARD },
  36.     { 80,   25,      16,    0x003, SETUP_STANDARD },
  37.     { 80,   43,      16,    0x003, SETUP_8X8_FNT  },
  38.     { 0,    0,      0,    UNSUP, 0          }
  39. };
  40.  
  41. #define MAX_GRAPH_MODES        40            /* maximum graphics mode table size */
  42. #define EGA_GRAPH_START        8            /* start of the EGA mode table */
  43. #define EGA_GRAPH_MODES        4            /* number of EGA graphics modes (incl end marker) */
  44. GrModeEntry graphics_mode_table[MAX_GRAPH_MODES] = {
  45.     { 320,  200,  16,    0x00d, SETUP_STANDARD },
  46.     { 640,  200,  16,    0x00e, SETUP_STANDARD },
  47.     { 640,  350,  16,    0x010, SETUP_STANDARD },
  48.     { 640,  480,  16,    0x012, SETUP_STANDARD },
  49.     { 320,  200,  256,  0x013, SETUP_STANDARD },
  50.     { 320,  240,  256,  0x013, SETUP_MODE_X   },
  51.     { 360,  480,  256,  0x013, SETUP_MODE_X   },
  52.     { 0,    0,      0,    UNSUP, 0          },
  53.     { 320,  200,  16,    0x00d, SETUP_STANDARD },    /* EGA table */
  54.     { 640,  200,  16,    0x00e, SETUP_STANDARD },
  55.     { 640,  350,  16,    0x010, SETUP_STANDARD },
  56.     { 0,    0,      0,    UNSUP, 0          }
  57. };
  58.  
  59. #include "pieces/chkevga.c"
  60. #include "pieces/chkvga.c"
  61. #include "pieces/vesainfo.c"
  62. #include "pieces/addmode.c"
  63. #include "paging/vesa.c"
  64.  
  65. int get_mem_size(int scan_line_len,int rows)
  66. {
  67.     _AX = scan_line_len;
  68.     _DX = rows;
  69.     asm mul dx;
  70.     asm add ax,4095;
  71.     asm adc dx,0;
  72.     asm mov cx,12;
  73.     asm shr ax,cl;
  74.     asm mov cx,4;
  75.     asm shl dx,cl;
  76.     asm add ax,dx;
  77.     return(_AX);        /* in 4 kByte units !! */
  78. }
  79.  
  80. int do_driver_init(void)
  81. {
  82.     VgaInfoBlock *vb;
  83.     ModeInfoBlock *mb;
  84.     short far *modeptr;
  85.     int mode,colors;
  86.  
  87.     if(!check_for_EGAVGA()) return(0);
  88.     if(!check_for_VGA()) {
  89.         HDR->driver_flags = GRD_EGA | GRD_NEW_DRIVER | GRD_NO_RW | GRD_128K;
  90.         HDR->memory_size = (128 / 4);
  91.         tblcopy(text_mode_table,&text_mode_table[EGA_TEXT_START],EGA_TEXT_MODES);
  92.         tblcopy(graphics_mode_table,&graphics_mode_table[EGA_GRAPH_START],EGA_GRAPH_MODES);
  93.         return(1);
  94.     }
  95.     HDR->memory_size = (256 / 4);
  96.     if((vb = VESAgetInfo()) != 0) {
  97.         modeptr = vb->VideoModePtr;
  98.         while((mode = *modeptr++) != (-1)) {
  99.         if((mb = VESAgetModeInfo(mode)) == 0) continue;
  100.         if((mb->ModeAttributes & MODE_EXTINFO) == 0) {
  101.             /* I am really delighted to have this mode, but.. */
  102.             /* what can I do with it without resolution info? */
  103.             continue;
  104.         }
  105.         if(mb->ModeAttributes & MODE_ISGRAPHICS) {
  106.             if(mb->BitsPerPixel < 16)
  107.             colors = 1 << mb->BitsPerPixel;
  108.             else if(mb->BitsPerPixel > 16)
  109.             colors = 0xc000U | mb->BitsPerPixel;
  110.             else if(VESAversion >= VESA_VERSION(1,2))
  111.             colors = mb->ReservedMaskSize ? 32768U : (0xc000 + 16);
  112.             else if(HDR->driver_options & GRD_15_PLANE_MODE)
  113.             colors = 32768U;
  114.             else colors = 0xc000 + 16;
  115.             add_graphics_mode(mb->XResolution,mb->YResolution,
  116.             colors,mode,SETUP_STANDARD
  117.             );
  118.             mode = get_mem_size(mb->BytesPerScanLine,mb->YResolution);
  119.             if(mb->MemoryModel == MODEL_4PLANE) mode <<= 2;
  120.             mode = (mode + (512/4 - 1)) & ~(512/4 - 1);        /* round up to next 0.5 MB */
  121.             if(HDR->memory_size < mode) HDR->memory_size = mode;
  122.         }
  123.         else {
  124.             add_text_mode(mb->XResolution,mb->YResolution,16,mode,SETUP_STANDARD);
  125.             if(mb->YResolution == 25) {
  126.             add_text_mode(mb->XResolution,28,16,mode,SETUP_8X14_FNT);
  127.             add_text_mode(mb->XResolution,50,16,mode,SETUP_8X8_FNT);
  128.             }
  129.         }
  130.         }
  131.     }
  132.     mode = GRD_256K;
  133.     if(HDR->memory_size >= (512  / 4)) mode = GRD_512K;
  134.     if(HDR->memory_size >= (1024 / 4)) mode = GRD_1024K;
  135.     if(HDR->memory_size >= (1536 / 4)) mode = GRD_1536K;
  136.     if(HDR->memory_size >= (2048 / 4)) mode = GRD_2048K;
  137.     if(HDR->memory_size >= (3072 / 4)) mode = GRD_3072K;
  138.     if(HDR->memory_size >= (4096 / 4)) mode = GRD_4096K;
  139.     HDR->driver_flags = GRD_VGA | GRD_NEW_DRIVER | GRD_NO_RW | mode;
  140.     return(1);
  141. }
  142.  
  143. #include "pieces/textfont.c"
  144. #include "pieces/mode_x.c"
  145.  
  146. int do_mode_set(GrModeEntry *md,int noclear,int *vw,int *vh,char *vflag)
  147. {
  148.     int BIOSno,memmode,pgmode;
  149.  
  150.     switch(md->mode.vdr.custom_setup_index) {
  151.         case SETUP_8X14_FNT:  return(mode_set_8x14_font(md,noclear));
  152.         case SETUP_8X8_FNT:      return(mode_set_8x8_font(md,noclear));
  153.         case SETUP_MODE_X:      return(mode_set_256_planar(md,noclear));
  154.     }
  155.     if((BIOSno = md->mode.vdr.BIOS_mode) > 0x13) {
  156.         if(noclear) BIOSno |= 0x8000;
  157.         _AX = VESA_FUNC + VESA_SET_MODE;
  158.         _BX = BIOSno;
  159.         geninterrupt(0x10);
  160.         if(_AX != VESA_SUCCESS) return(-1);
  161.     }
  162.     else {
  163.         if(noclear) BIOSno |= 0x80;
  164.         _AX = BIOSno;
  165.         geninterrupt(0x10);
  166.     }
  167.     pgmode = setup_VESA_paging(md);
  168.     if(pgmode == (-1)) return(-1);
  169.     switch((unsigned)md->number_of_colors) {
  170.         case 2U:         memmode = GRD_1_PLANE;  break;
  171.         case 16U:         memmode = GRD_4_PLANES; break;
  172.         case 256U:         memmode = (HDR->driver_options & GRD_FAST_256_MODE) ? GRD_8_F_PLANES : GRD_8_PLANES; break;
  173.         case 32768U:     memmode = GRD_16_PLANES;    break;
  174.         case 0xc000U+16: memmode = GRD_16_R_PLANES; break;
  175.         case 0xc000U+24: memmode = GRD_24_PLANES;    break;
  176.         default:         return(-1);
  177.     }
  178.     if((md->number_of_colors > 256) && (VESAversion >= VESA_VERSION(1,2))) {
  179.         ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode);
  180.         if(mb) {
  181.         HDR->r_mask = mb->RedMaskSize;
  182.         HDR->r_offs = mb->RedMaskPos;
  183.         HDR->g_mask = mb->GreenMaskSize;
  184.         HDR->g_offs = mb->GreenMaskPos;
  185.         HDR->b_mask = mb->BlueMaskSize;
  186.         HDR->b_offs = mb->BlueMaskPos;
  187.         HDR->f_mask = mb->ReservedMaskSize;
  188.         HDR->f_offs = mb->ReservedMaskPos;
  189.         /* is that 16 really only 15 ? */
  190.         if((memmode == GRD_16_R_PLANES) && (HDR->f_mask > 0)) memmode = GRD_16_PLANES;
  191.         }
  192.     }
  193.     if((*vw > md->width) || (*vh > md->height)) {
  194.         int virw = *vw;
  195.         int virh = *vh;
  196.         _BX = (virw > md->width) ? 0 : 1;           /* inquire only if width stays the same */
  197.         _CX = virw;
  198.         _AX = VESA_FUNC + VESA_SCAN_LNLEN;
  199.         geninterrupt(0x10);
  200.         if(_AX == VESA_SUCCESS) {
  201.         virw = _CX;
  202.         virh = _DX;
  203.         HDR->line_offset = _BX;
  204.         if((virw > md->width) || (virh > md->height)) {
  205.             *vw = virw;
  206.             *vh = virh;
  207.             *vflag = 1;
  208.         }
  209.         }
  210.     }
  211.     return((HDR->driver_flags & ~(GRD_PLANE_MASK | GRD_PAGING_MASK)) | memmode | pgmode);
  212. }
  213.  
  214. void do_screen_start_set(int *cp,int *rp)
  215. {
  216.     _CX = *cp;
  217.     _DX = *rp;
  218.     _BX = 0;
  219.     _AX = VESA_FUNC + VESA_DISP_START;
  220.     geninterrupt(0x10);
  221.     if(_AX == VESA_SUCCESS) {
  222.         *cp = _CX;
  223.         *rp = _DX;
  224.     }
  225. }
  226.  
  227. #include "pieces/vdrmain.c"
  228.  
  229.